﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Driver.Properties;
using log4net;
using Lucene.Net.Store;
using LuceneIndexer;
using LuceneSearcher;
using MarketDataAnalyzer;
using Directory = System.IO.Directory;

namespace Driver
{
    static class Driver
    {
        private static readonly ILog Logger =
            LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private static readonly SimpleFSLockFactory LockFactory = new SimpleFSLockFactory();
        private static ISearcher searcher;
        private static FSDirectory directory;
        private static Indexer indexer;
        private static IEnumerable<PriceAnalysis> inputAnalyses;
        private static IEnumerable<SearchResult> matches;
        private static string fileName;
        private static DateTime splitDate;
        private static double matchScoreThreshold;

        private const string DateFormat = "yyyyMMdd-HH.mm.ss";

        static Driver()
        {
            var indexPath = Settings.Default.IndexDir;
            if (!Directory.Exists( indexPath ))
            {
                throw new IOException( indexPath + " directory does not exist" );
            }
            var files = Directory.GetFiles( indexPath );
            foreach (var file in files)
            {
                File.Delete( file );
            }
            var indexInfo = new DirectoryInfo( indexPath );
            directory = FSDirectory.Open( indexInfo, LockFactory );
            indexer = new Indexer( directory );

            Logger.Debug("Starting Driver...");

            matchScoreThreshold = Settings.Default.MatchScoreThreshold;
            Logger.DebugFormat("Using matchScoreThreshold of [{0}].", matchScoreThreshold);
            splitDate = new DateTime(2011, 01, 25);
            Logger.DebugFormat("Using a split date of {0}", splitDate.ToShortDateString());
        }

        static void Main()
        {
            #region SimpleLucene

            Logger.DebugFormat("Starting SimpleLucene Analyzer...");

            indexer.IndexNewsItems(splitDate);

            searcher = new SimpleLuceneSearcher(directory);
            matches = searcher.SearchNewsItems(splitDate);
            matches = matches.Where(sr => sr.BestMatchScore >= matchScoreThreshold).ToList();
            inputAnalyses = MarketDataAnalyzer.MarketDataAnalyzer.Analyze(matches);

            fileName = string.Format("PriceAnalyses_SimpleLucene_{0}.csv",
                                          DateTime.UtcNow.ToString(DateFormat));
            OutputUtilities.WriteAnalysesToFileHumanReadable(fileName, inputAnalyses);
            OutputUtilities.WriteAnalysesToFileCsv(fileName, inputAnalyses);

            searcher = null;

            #endregion

            #region SynonymLucene

            Logger.DebugFormat("Starting SynonymLucene Analyzer...");

            var synonymDirectoryPath = Settings.Default.SynonymIndexDir;
            var synonymDirectoryInfo = new DirectoryInfo(synonymDirectoryPath);
            var synonymDirectory = FSDirectory.Open(synonymDirectoryInfo, LockFactory);

            searcher = new SynonymLuceneSearcher(directory, synonymDirectory);
            matches = searcher.SearchNewsItems(splitDate);
            matches = matches.Where(x => x.BestMatchScore >= matchScoreThreshold).ToList();
            inputAnalyses = MarketDataAnalyzer.MarketDataAnalyzer.Analyze(matches);

            fileName = string.Format("PriceAnalyses_SynonymLucene_{0}.csv",
                                      DateTime.UtcNow.ToString(DateFormat));
            OutputUtilities.WriteAnalysesToFileHumanReadable(fileName, inputAnalyses);
            OutputUtilities.WriteAnalysesToFileCsv(fileName, inputAnalyses);

            #endregion

            #region Random

            Logger.DebugFormat("Starting Random Analyzer...");

            searcher = new RandomSearcher();
            var randomSearchResults = new List<SearchResult>();
            // Run the random multiple times to get a truer sampling
            for (int i = 0; i < 10; i++)
            {
                randomSearchResults.AddRange( searcher.SearchNewsItems( splitDate ).ToList() );
            }
            inputAnalyses = MarketDataAnalyzer.MarketDataAnalyzer.Analyze( randomSearchResults );

            fileName = string.Format( "PriceAnalyses_Random_{0}.csv", DateTime.UtcNow.ToString( DateFormat ) );
            OutputUtilities.WriteAnalysesToFileHumanReadable( fileName, inputAnalyses );
            OutputUtilities.WriteAnalysesToFileCsv( fileName, inputAnalyses );

            #endregion

            Logger.Info( "Analyzer complete." );
        }
    }
}
